/*
 * TacticaDemo01.java
 *
 * Created on 16 de julio de 2006, 13:20
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package futbol.tacticas.concursantes2007.La_Enmascarada;

import futbol.tacticas.concursantes.Tactica;

import java.awt.Point;
import java.util.Vector;

import futbol.tacticas.SituacionJugadores;

public class TacticaSilviaN extends TacticaSilviaI implements Tactica
{

  //---------------------------------------------//
  // VALORES INICIALES
  //---------------------------------------------//
	
	/*
	 * Definicin de los Jugadores
	 */
//    private int nValores[][]=
//    {
//        {-152,  0,      4},     // 1
//        {-110,  68,     5},     // 2
//        {-110,  30,     5},     // 3
//        {-120,  0,      4},     // 4   
//        {-110,  -30,    5},     // 5
//        {-110,  -68,    5},     // 6
//        {-40,   50,     4},     // 7
//        {-40,   0,      5},     // 8
//        {-40,   -50,    5},     // 9
//        {80,    65,     7},     // 10   
//        {100,   -35,    6}      // 11
//    };
    /**
     * Definician de los lmites de marcaje
     * (0 => Mantener la posicin)
     */
    private int nLimiteMarcaje[]=
    {
        50,     // 1
        80,     // 2
        50,     // 3
        30,      // 4   
        50,     // 5
        80,     // 6
        90,     // 7
        80,     // 8
        60,     // 9
        50,     // 10   
        50      // 11
    };
//    {
//        20,     // 1
//        50,     // 2
//        20,     // 3
//        5,      // 4   
//        20,     // 5
//        50,     // 6
//        80,     // 7
//        50,     // 8
//        40,     // 9
//        20,     // 10   
//        20      // 11
//    };
    
  //---------------------------------------------//
  // ATRIBUTOS
  //---------------------------------------------//
    
  //---------------------------------------------//
	// CONSTRUCTOR
  //---------------------------------------------//
	
    
  //---------------------------------------------//
  // MTODOS DE LA INTERFAZ
  //---------------------------------------------//
  
  public String getNombre()
  {
    
    return "La_Enmascarada Normal";
  }
  
  /**
   * Devuelve la coordenada inicial X de los jugadores.
   */
  public int getXInicial(int n)
  {
    int xInicial = 0;
    // Lnea de Porteros
    if (n == 0)         // 1: portero 
      xInicial = -152;   // 0
    // Laterales
    else if ( 
        (n == 1)    // 2: lateral (derecho) 
        || 
        (n == 2)    // 3: lateral (izquierdo)
       )
    {
      xInicial = -100; 
    }
    // Centrales
    else if ( 
        (n == 4)    // 5: defensa (derecho)
        || 
        (n == 5)    // 6: defensa (izquierdo)
       )
    {
      xInicial = -110;
    }
    else if (n == 3)    // 4: libero
      xInicial = -120;
    else if (n == 6)    // 7: mediocentro
      xInicial = -75;
    // Interiores
    else if ( 
        (n == 7)    // 8: interior (derecho)
        || 
        (n == 8)    // 9: interior (izquierdo)
       )
    {
      xInicial = -40;
    }
    else if (n == 9)    //10: delantero (mediapunta) 
      xInicial = 80;
    else if (n == 10)   //11: delantero centro
      xInicial = 100;

    return xInicial;
  }
  
  /**
   * Devuelve la coordenada inicial Y de los jugadores.
   */
  public int getYInicial(int n)
  {
    int yInicial = 0;
    // Lnea centrada
    if (n == 0)         // 1: portero 
      yInicial = 0;   // 0
    else if (n == 1)    // 2: lateral (derecho) 
      yInicial = 70;
    else if (n == 2)    // 3: lateral (izquierdo)
      yInicial = 70 * -1;
    else if (n == 3)    // 4: libero
      yInicial = 0;
    else if (n == 4)    // 5: defensa (derecho)
      yInicial = 30;
    else if (n == 5)    // 6: defensa (izquierdo)
      yInicial = 30 * -1;
    else if (n == 6)    // 7: mediocentro
      yInicial = 0;
    else if (n == 7)    // 8: interior (derecho)
      yInicial = 50;
    else if (n == 8)    // 9: interior (izquierdo)
      yInicial = 50 * -1;
    else if (n == 9)    //10: delantero (mediapunta) 
      yInicial = 50;
    else if (n == 10)   //11: delantero centro
      yInicial = 30 * -1;
    
    return yInicial;
  }

  
  //---------------------------------------------//
  // MTODOS AUXILIARES
  //---------------------------------------------//

  //---------------------------------------------//
  /**
   * Retorna los identificadores de los porteros. 
   */
  protected int[] getPortero()
  {
    int[] result = new int[1];
    result[0] = 0;
    return result;
  }
  
  //---------------------------------------------//
  /**
   * Retorna los identificadores de los defensas. 
   */
  protected int[] getDefensas()
  {
    int[] result = new int[5];
    result[0] = 1;
    result[1] = 2;
    result[2] = 3;
    result[3] = 4;
    result[4] = 5;
    return result;
  }
  //---------------------------------------------//
  /**
   * Retorna el identificador del defensa libre. 
   */
  protected int getLibero()
  {
    return 3;
  }
  //---------------------------------------------//
  
  /**
   * Retorna los identificadores de los medios. 
   */
  protected int[] getMedios()
  {
    int[] result = new int[3];
    result[0] = 6;
    result[1] = 7;
    result[2] = 8;
    return result;
  }
  //---------------------------------------------//
  /**
   * Retorna el identificador del medio organizador. 
   */
  protected int getMedioCentro()
  {
    return 7;
  }
  
  //---------------------------------------------//
  /**
   * Retorna los identificadores de los delanteros. 
   */
  protected int[] getDelanteros()
  {
    int[] result = new int[2];
    result[0] = 9;
    result[1] = 10;
    return result;
  }
  //---------------------------------------------//
  /**
   * Retorna el identificador del delantero mas adelantado. 
   */
  protected int getDelanteroCentro()
  {
    return 10;
  }
  
  //---------------------------------------------//
  /**
   * Retorna los movimientos del portero.
   */
  protected Vector<CD> m1( SituacionJugadores sj)
  {
    Vector<CD> comandos = new Vector<CD>();

    Point pelota = sj.getBola();
    int y = (int)(pelota.getY() / 2);
    if (y < -20) 
      y = -20;
    if (y > 20)
      y = 20;
    int[] porteros = this.getPortero();
    int x;
    boolean isArea = isArea(pelota);
    double distContrarioPelota = distContrarioCercaPelota(sj);
    Point portero;
String debugStr = "";
    for (int n=0; n < porteros.length; n++)
    {
      // por defecto el portero vuelva a su posicin horizontal
      x = this.getXInicial(porteros[n]);
      portero = sj.getMisJugadores()[porteros[n]];
      // Si la pelota est en el rea ...
      if (isArea)
      {
debugStr = "Pelota en el area ";        
//System.out.println("VELOCIDAD = "+this.lastVelocidad);
        // ... y va muy despacio (es decir, no es un tiro) ...
        if (this.lastVelocidad < 10)
        {
debugStr = debugStr + " despacio ";        
          // ... si hay opcin de intentar llegar antes que el delantero
          if (distContrarioPelota > portero.distance(pelota))
          {
debugStr = debugStr + " y portero mas cerca que delantero = ACHIQUE "+pelota;        
            // Y hacia el baln
            x = pelota.x;
            y = pelota.y;
          }
        }
      }
      comandos.add(CD.newComandoIrA(porteros[n], x, y));
      
if (DEBUG_MOVE_POR)
  System.err.println(debugStr);
  
    }
    return comandos;
  }

  //---------------------------------------------//
  /**
   * Retorna los movimientos de la defensa.
   */
  protected Vector<CD> m2( SituacionJugadores sj)
  {
    Vector<CD> comandos = new Vector<CD>();
/**** Mejorar defensa **/
// TODO: Comprobar que no hay ningn delantero suelto
      Point bola=sj.getBola();
      Point jugadores[]=sj.getMisJugadores();
//      Point contrarios[]=sj.getContrario();

// Sil-1      
//      int lineaPresion = -25;
int lineaPresion = 0;
//      int max_distancia_origen = 1;//100;
//      double dist_def_del;
      double dist_def_ori;
      Point origen;
// Sil-1      
// TEST -- 1 -- DEFENSA SIEMPRE
//lineaPresion = 160;    
if (bola.getX() < (0+lineaPresion))
//      if ((false == sj.estoyMasCercaDeBola()) || (bola.getX() < (0+lineaPresion)))
      {
  int nLinero = this.getLibero();
  
  
//        int min_defensa = 1;
//        int max_defensa = 5;
        int cerca = 20;
        Point posicionMarcaje;
//        int direccion = -1; // adelantarse al delantero rival
        int[] defensas = this.getDefensas();
//        int[] delanterosMarcados = new int[11];
        int defensaN;
String debugStr;
        for (int i=0;i<defensas.length;i++)
        {
          defensaN = defensas[i];
debugStr = "Calculando marcaje para n="+defensaN;
          // No movemos el libero (via nLimiteMarcaje)
          if (defensaN != nLinero)
          {
            origen = new Point( this.getXInicial(defensaN), this.getYInicial(defensaN));
            dist_def_ori = Math.abs(origen.distance(jugadores[defensaN]));
            if ( dist_def_ori <= nLimiteMarcaje[defensaN])
            {
              // Presion
              int nJC = sj.getContrarioMasCerca(jugadores[defensaN].getX(), jugadores[defensaN].getY());
//              direccion = -1; // Buscar rechace
              posicionMarcaje = cortarPaseDireccionDelantero(nJC, cerca, sj);
              comandos.add(CD.newComandoIrA(defensaN, posicionMarcaje.getX(), posicionMarcaje.getY()));
//              dist_def_del = Math.abs(contrarios[nJC].distance(jugadores[n]));
//                if ( contrarios[nJC].getX()  )
//              comandos.add(new ComandoIrA(n, contrarios[nJC].getX()+cerca*direccion, contrarios[nJC].getY()));
debugStr = debugStr + " : mancar al rival ="+nJC+" (en "+sj.getContrario()[nJC]+") desde : "+posicionMarcaje;
            }
            else
            {
              // Mantener posicin
debugStr = debugStr + " : mantener posicin";
            }
          }
          else
          {
            // Libero
            int y = (int) bola.getY();
            if (y < -40) 
              y = -40;
            if (y > 40)
              y = 40;
            comandos.add(CD.newComandoIrA(defensaN, jugadores[defensaN].getX(), y));
debugStr = debugStr + " : libero bascula "+y;
          }
if (DEBUG_MOVE_DEF)
  System.err.println(debugStr);
        }
      }
if (DEBUG_MOVE_DEF)    
System.err.println(" ------------------------------------ m2");
    return comandos;
  }

  //---------------------------------------------//
  /**
   * Retorna los movimientos del mediocampo.
   */
  protected Vector<CD> m3( SituacionJugadores sj)
  {
    Vector<CD> comandos = new Vector<CD>();
    // Achique en la media
    Point origen;
    double dist_ori;
    int nJug;
String debugStr;
    for (int i = 0; i < this.getMedios().length; i++) 
    {
      nJug = this.getMedios()[i];
      origen = new Point( this.getXInicial(nJug), this.getYInicial(nJug));
      dist_ori = Math.abs(origen.distance(sj.getMisJugadores()[nJug]));
  
      if ( dist_ori <= nLimiteMarcaje[nJug])
      {
debugStr = "Movimiento de achique para el medio n="+nJug+"\t lejosOrigen="+dist_ori+" [ "+nLimiteMarcaje[nJug]+" ]\t balon="+sj.getBola();
        comandos.add(CD.newComandoIrA(nJug, sj.getBola().getX() , sj.getBola().getY()));
if (DEBUG_MOVE_MED)
  System.err.println(debugStr);
      }
    }
if (DEBUG_MOVE_MED)    
System.err.println(" ------------------------------------ m3");
    
    return comandos;
  }
  
  //---------------------------------------------//
  /**
   * Retorna los movimientos de la delantera.
   */
  protected Vector<CD> m4( SituacionJugadores sj)
  {
    Vector<CD> comandos = new Vector<CD>();
    
//    // Si la pelota est en el rea, buscar rechace
//    if (sj.getBola().getX() > 100)
//    {
      int nJug;
      Point delanteroPos;
      double x,y;
String debugStr = "";
      for (int i = 0; i < this.getDelanteros().length; i++) 
      {
        nJug = this.getDelanteros()[i];
        delanteroPos = sj.getMisJugadores()[nJug];
debugStr = "Calculando rechace para n="+nJug+" en "+delanteroPos;
        // Si la pelota est en el rea, buscar rechace
        if (sj.getBola().getX() > 100)
        {
          if (delanteroPos.x < 100)
          {
//          if (delanteroPos.x < )
            x = 100 + (160 - 100)/2;
            if (delanteroPos.y > 0)
              y = 30;
            else
              y = 0 - 30;
            comandos.add(CD.newComandoIrA(nJug, x, y));
debugStr = debugStr + " : hacia x="+x+" , y="+y;
          
          }
          else
debugStr = debugStr + " : mantener posicin";
        }
        else
        {
          // Desmarcar
          if (sj.getBola().getX() < -40)
          {
            // Intercambiar posiciones
            int otroDelantero = (i + 1) % this.getDelanteros().length;
            otroDelantero = this.getDelanteros()[otroDelantero];
            comandos.add(CD.newComandoIrA(nJug, this.getXInicial(otroDelantero), this.getYInicial(otroDelantero)));
debugStr = debugStr + " : desmarcar con el delantero n="+otroDelantero+"\t hacia x="+this.getXInicial(otroDelantero)+" , y="+this.getYInicial(otroDelantero);
          }
        }
      }
if (DEBUG_MOVE_DEL)
  System.err.println(debugStr);
//    }
    
if (DEBUG_MOVE_DEL)    
System.err.println(" ------------------------------------ m4");

    return comandos;
  }
  
  //---------------------------------------------//
  /**
   * Retorna los movimientos relativos al achique del baln.
   */
  protected Vector<CD> m5( SituacionJugadores sj)
  {
    Vector<CD> comandos = new Vector<CD>();
/** 5NO BOLA **/
    int nJug = sj.getMasCercanoDeBola();
//    Point origen = new Point( this.getXInicial(nJug), this.getYInicial(nJug));
//    double dist_ori = Math.abs(origen.distance(sj.getMisJugadores()[nJug]));

    // El portero posee un comportamiento especial con la pelota,
    //  achicando slo cuando las condiciones de velocidad del baln 
    //  lo permiten.
    if (nJug == 0)
    {
      int[] info = sj.getInfoMasCercano(sj.getMisJugadores(), sj.getBola(), new int[]{0}, false);
      nJug = info[0];
    }
//    if ((nJug != 0) || (dist_ori <= nLimiteMarcaje[nJug]))  // Acecar al portero si esta cerca
      comandos.add(CD.newComandoIrA(nJug, sj.getBola().getX() , sj.getBola().getY()));

    // Movilizar jugadores para realizar presin (p.e. medio centro)
    // - Se podra intentar posicionar al segundo jugador ms cercano
    //    de manera que continuara la presin o se situara a modo de barrera
    //    entre el baln y la propia meta.
/****/
//    // Acercar al mediocentro
//    if (nJug != this.getMedioCentro())
//    {
//      nJug = this.getMedioCentro();
//      if ( dist_ori <= nLimiteMarcaje[nJug])
//        comandos.add(new ComandoIrA(nJug, sj.getBola().getX() , sj.getBola().getY()));
//    }
/****/
    return comandos;
  }
  
  //---------------------------------------------//
  /**
   * Retorna los pases
   */
  protected Vector<CD> g1( SituacionJugadores sj)
  {
    Vector<CD> comandos = new Vector<CD>();
//    int[] porteros = this.getPortero();
//    int[] defensas = this.getDefensas();
//    int[] medios = this.getMedios();
//    int[] delanteros = this.getDelanteros();
    
    /*** CALCULAR MEJOR PASE ***/
    {
//      int jugador = 7;
//      int jugador = sj.getMasCercanoDeBola();
      int numJugadoresPase = 3;
      int jugador;
      int fuerza;
      int limiteMin;
      int limiteMax;
      int riesgo;
      boolean soloAdelante = true;
      
      int[] probarJugadores = sj.getInfoMasCercano(sj.getMisJugadores(), sj.getBola(), null, false);
      jugador = probarJugadores[0];
      
      int[] jugadoresProbados = new int[numJugadoresPase];
      for (int i = 0; i < numJugadoresPase; i++)
        jugadoresProbados[i] = jugador;

      for (int i = 0; i < numJugadoresPase; i++)
      {
        fuerza = this.getFuerza(jugador);
        limiteMin = fuerza * 2;
        limiteMax = fuerza * 5;
        riesgo = 30;
        
        Point mejorPase = super.calculaMejorPase(sj, jugador, soloAdelante, limiteMin, limiteMax, riesgo);

//// Borrar
//if ((jugador == 7) || (jugador == 8)|| (jugador == 6))
//{
//  Point pto = sj.getMisJugadores()[jugador];
//comandos.add(CD.newComandoGolpearBola(jugador, pto.getX()+40, pto.getY()));
////if (sj.getBola().distance(pto) <= 10)
////comandos.add(CD.newComandoIrA(7, pto.getX() + 10 , pto.getY()));
//}
//else  
//  comandos.add(CD.newComandoPase(jugador, 7));    
        
        
        comandos.add(CD.newComandoGolpearBola(jugador, mejorPase.getX(), mejorPase.getY()));

        // Actualizamos el jugador para la siguiente iteracion
        jugadoresProbados[i] = jugador;
        probarJugadores = sj.getInfoMasCercano(sj.getMisJugadores(), sj.getBola(), jugadoresProbados, false);
        jugador = probarJugadores[0];
      }
//      int fuerza = this.getFuerza(jugador);
//      int limiteMin = fuerza * 2;
//      int limiteMax = fuerza * 5;
//      int riesgo = 30;
//      Point mejorPase = super.calculaMejorPase(sj, jugador, false, limiteMin, limiteMax, riesgo); 
//      comandos.add(new ComandoGolpearBola(7, mejorPase.getX(), mejorPase.getY()));
    }
    /**********/
    
//    // Portero aleja
//    for (int i = 0; i < porteros.length; i++) 
//    {
//      comandos.add(new ComandoPase(porteros[i], delanteros[delanteros.length-1]));
//    }
//    // Defensa aleja
//    for (int i = 0; i < defensas.length; i++) 
//    {
//      if (defensas[i] == 1)       // Lateral Der -> Interior Der
//        comandos.add(new ComandoPase(defensas[i], 6));
//      else if (defensas[i] == 5)  // Lateral Izq -> Interior Izq
//        comandos.add(new ComandoPase(defensas[i], 8));
//      else
//        comandos.add(new ComandoPase(defensas[i], this.getMedioCentro()));
//    }
//    // Media centra o chuta
//    int desviacion = 0;
//    for (int i = 0; i < medios.length; i++) 
//    {
//      if (medios[i] == 6)             // Interior Der -> Del Der
//        comandos.add(new ComandoPase(medios[i], 9));
//      else if (medios[i] == 8)        // Interior Izq -> Del Izq
//        comandos.add(new ComandoPase(medios[i], 10));
//      else
//      {
////        desviacion ++;
//        comandos.add(new ComandoTiroAPuerta(medios[i], desviacion));
//      }
//    }
    
    return comandos;
  }
  
  //---------------------------------------------//
  /**
   * Retorna los disparos a puerta
   */
  protected Vector<CD> g2( SituacionJugadores sj)
  {
    Vector<CD> comandos = new Vector<CD>();
    
//    int[] porteros = this.getPortero();
//    int[] defensas = this.getDefensas();
    int[] medios = this.getMedios();
    int[] delanteros = this.getDelanteros();
    
    int desviacion = 0;
    
String debugStr = "";

    int porteroRival = sj.getContrarioMasCerca(160, 0);
    Point porteroRivalPos = sj.getContrario()[porteroRival];

    // Si Media cerca chuta
    for (int i = 0; i < medios.length; i++) 
    {
      if (sj.getMisJugadores()[medios[i]].x > 65)
      {
      desviacion = calcularDesviacionTiro(sj.getMisJugadores()[medios[i]], porteroRivalPos);
if (DEBUG_BOLA_TIRO)    
System.err.println(" \t\t desviacion para n="+medios[i]+" = "+desviacion);
        
        comandos.add(CD.newComandoTiroAPuerta(medios[i], desviacion));
      }
    }
    
    // Delantera chuta
    for (int i = 0; i < delanteros.length; i++) 
    {
      desviacion = calcularDesviacionTiro(sj.getMisJugadores()[delanteros[i]], porteroRivalPos);
if (DEBUG_BOLA_TIRO)    
System.err.println(" \t\t desviacion para n="+delanteros[i]+" = "+desviacion);

      comandos.add(CD.newComandoTiroAPuerta(delanteros[i], desviacion));
    }
if (DEBUG_BOLA_TIRO)    
System.err.println(" ------------------------------------ g2");
    
    return comandos;
  }
  
}
